<?php

/**
 * MyQEE 字符串处理类
 *
 * @author	 jonwang(jonwang@myqee.com)
 * @category   MyQEE
 * @package	System
 * @subpackage Core
 * @copyright  Copyright (c) 2008-2011 myqee.com
 * @license	http://www.myqee.com/license.html
 */
class MyQEE_Str
{

    /**
     * 字符串
     * @var string
     */
    protected $data;

    public function __construct($data)
    {
        $this->data = $data;
    }

    public function __toString()
    {
        return (string)$this->data;
    }

    /**
     * 返回实例化对象
     * @param array $data
     * @return Str
     */
    public static function factory($data)
    {
        return new Str($data);
    }

    /**
     * 获取字符串
     */
    public function toString()
    {
        return $this->__toString();
    }

    public function addcslashes($charlist)
    {
        return addcslashes($this->data, $charlist);
    }

    /**
     * 过滤字符
     */
    public function xss()
    {

    }

    public function substr($start, $length = null, $encoding = 'utf-8')
    {
        static $supper_mb = null;
        if (null===$supper_mb)
        {
            $supper_mb = function_exists('mb_substr');
        }
        if ( $supper_mb )
        {
            if ( null === $length )
            {
                return mb_substr($this->data, $start, null, $encoding);
            }
            else
            {
                return mb_substr($this->data, $start, $length, $encoding);
            }
        }
        else
        {
            $str = $this->data;

            if ( self::is_ascii($str) ) return ($length === NULL) ? substr($str, $start) : substr($str, $start, $length);

            // Normalize params
            $str = (string)$str;
            $strlen = self::strlen($str);
            $start = (int)($start < 0) ? max(0, $strlen + $start) : $start; // Normalize to positive offset
            $length = ($length === NULL) ? NULL : (int)$length;

            // Impossible
            if ( $length === 0 or $start >= $strlen or ($length < 0 and $length <= $start - $strlen) ) return '';

            // Whole string
            if ( $start == 0 and ($length === NULL or $length >= $strlen) ) return $str;

            // Build regex
            $regex = '^';

            // Create an offset expression
            if ( $start > 0 )
            {
                // PCRE repeating quantifiers must be less than 65536, so repeat when necessary
                $x = (int)($start / 65535);
                $y = (int)($start % 65535);
                $regex .= ($x == 0) ? '' : '(?:.{65535}){' . $x . '}';
                $regex .= ($y == 0) ? '' : '.{' . $y . '}';
            }

            // Create a length expression
            if ( $length === NULL )
            {
                $regex .= '(.*)'; // No length set, grab it all
            } // Find length from the left (positive length)
            elseif ( $length > 0 )
            {
                // Reduce length so that it can't go beyond the end of the string
                $length = min($strlen - $start, $length);

                $x = (int)($length / 65535);
                $y = (int)($length % 65535);
                $regex .= '(';
                $regex .= ($x == 0) ? '' : '(?:.{65535}){' . $x . '}';
                $regex .= '.{' . $y . '})';
            } // Find length from the right (negative length)
            else
            {
                $x = (int)(- $length / 65535);
                $y = (int)(- $length % 65535);
                $regex .= '(.*)';
                $regex .= ($x == 0) ? '' : '(?:.{65535}){' . $x . '}';
                $regex .= '.{' . $y . '}';
            }

            preg_match('/' . $regex . '/us', $str, $matches);
            return $matches[1];
        }
    }

    /**
     * 文本转换为HTML
     * 将处理<>和换行符
     */
    public function text2html()
    {
        return str_replace(array('<', '>', "\r\n", "\r", "\n"), array('&lt;', '&gt;', '<br />', '<br />', '<br />'), $this->data);
    }

    /**
     * 字符串长度
     * @param $encoding 字符编码，默认utf-8
     */
    public function strlen($encoding = 'utf-8')
    {
        return mb_strlen($this->data, $encoding);
    }

    /**
     * 字符串长度
     * @param $encoding 字符编码，默认utf-8
     */
    public function count($encoding = 'utf-8')
    {
        return $this->strlen($encoding);
    }

    /**
     * 追加数据
     *
     * @param string $value
     */
    public function append($value)
    {
        $this->data .= $value;
        return $this;
    }

    public function is_empty()
    {
        return empty($this->data);
    }

    public function ubb2html()
    {
        return bbcode::parse($this->data);

        $tmpstr = '';
        $tcontent = $this->data;
        if ( ! empty($tcontent) )
        {
            $tcontent = str_replace(array('<', '>', "\r\n", "\r", "\n"), array('&lt;', '&gt;', '<br />', '<br />', '<br />'), $tcontent);
            $tcontent = preg_replace('/\[br\]/is', "<br />", $tcontent);

            //******************************************************************
            $tRegexAry = array();
            $tRegexAry[] = array('\[p\]([^\[]*?)\[\/p\]', "\\1<br />");
            $tRegexAry[] = array('\[b\]([^\[]*?)\[\/b\]', "<b>\\1</b>");
            $tRegexAry[] = array('\[i\]([^\[]*?)\[\/i\]', "<i>\\1</i>");
            $tRegexAry[] = array('\[u\]([^\[]*?)\[\/u\]', "<u>\\1</u>");
            $tRegexAry[] = array('\[ol\]([^\[]*?)\[\/ol\]', "<ol>\\1</ol>");
            $tRegexAry[] = array('\[ul\]([^\[]*?)\[\/ul\]', "<ul>\\1</ul>");
            $tRegexAry[] = array('\[li\]([^\[]*?)\[\/li\]', "<li>\\1</li>");
            $tRegexAry[] = array('\[quote\]([^\[]*?)\[\/quote\]', "<div class=\"ubb_quote\">\\1</div>");
            $tRegexAry[] = array('\[color=([^\]]*)\]([^\[]*?)\[\/color\]', "<font style=\"color: \\1\">\\2</font>");
            $tRegexAry[] = array('\[hilitecolor=([^\]]*)\]([^\[]*?)\[\/hilitecolor\]', "<font style=\"background-color: \\1\">\\2</font>");
            $tRegexAry[] = array('\[align=([^\]]*)\]([^\[]*?)\[\/align\]', "<div style=\"text-align: \\1\">\\2</div>");
            $tRegexAry[] = array('\[url=([^\]]*)\]([^\[]*?)\[\/url\]', "<a href=\"\\1\" target=\"_blank\">\\2</a>");
            $tRegexAry[] = array('\[img\]([^\[]*?)\[\/img\]', "<a href=\"\\1\" target=\"_blank\"><img src=\"\\1\" /></a>");
            //******************************************************************
            $tState = true;
            while ( $tState )
            {
                $tState = false;
                for( $ti = 0; $ti < count($tRegexAry); $ti ++ )
                {
                    $tnRegexString = "/" . $tRegexAry[$ti][0] . "/is";
                    if ( preg_match($tnRegexString, $tcontent) )
                    {
                        $tState = true;
                        $tcontent = preg_replace($tnRegexString, $tRegexAry[$ti][1], $tcontent);
                    }
                }
            }
            //******************************************************************
            $tmpstr = $tcontent;
        }
        return $tmpstr;
    }

    /**
     * 等同js脚本里的escape函数
     *
     * @param string $str
     * @param string $encode
     */
    public function escape($encode = 'UTF-8')
    {
        $encode = strtoupper($encode);
        if ( $encode == 'UTF-8' )
        {
            preg_match_all("/[\xC0-\xE0].|[\xE0-\xF0]..|[\x01-\x7f]+/", $this->data, $r);
        }
        else
        {
            preg_match_all("/[\x80-\xff].|[\x01-\x7f]+/", $this->data, $r);
        }
        //prt($r);
        $ar = $r[0];
        foreach ( $ar as $k => $v )
        {
            $ord = ord($v[0]);
            if ( $ord <= 128 )
            {
                $ar[$k] = rawurlencode($v);
            }
            else
            {
                $ar[$k] = "%u" . bin2hex(iconv($encode, "UCS-2BE", $v));
            }
        } //foreach
        return join("", $ar);
    }

    /**
     * 等同js脚本里的unescape函数
     * @param string $encode
     */
    public function unescape($encode = 'UTF-8')
    {
        $encode = strtoupper($encode);
        if ( $encode == 'GBK' || $encode == 'GB2312' )
        {
            $substrStrNum = 2;
        }
        else
        {
            $substrStrNum = 3;
        }
        $str = rawurldecode($this->data);
        preg_match_all('#%u.{4}|&#x.{4};|&#\d+;|&#\d+?|.+#U', $str, $r);
        $ar = $r[0];
        foreach ( $ar as $k => $v )
        {
            if ( substr($v, 0, 2) == "%u" ) $ar[$k] = iconv("UCS-2BE", $encode, pack("H4", substr($v, - 4)));
            elseif ( substr($v, 0, 3) == "&#x" ) $ar[$k] = iconv("UCS-2BE", $encode, pack("H4", substr($v, $substrStrNum, - 1)));
            elseif ( substr($v, 0, 2) == "&#" )
            {
                $ar [$k] = iconv ( "UCS-2BE", $encode, pack ( "n", preg_replace ( '#[^\d]#', "", $v ) ) );
            }
        }
        return join ( "", $ar );
    }

    /**
     * 返回当前字符的拼音
     *
     * @return string
     */
    public function pinyin()
    {
        return PinYin::get($this->data);
    }

    public static function __set_state($arr)
    {
        return $arr['data'];
    }

    protected static function _code_format($code)
    {
        return '<div class="ubb_code"><pre class="brush: php">' . $code . '</pre></div>';
    }
}